package high.concurent.service.impl;

import com.google.code.kaptcha.Producer;
import high.concurent.constant.MailConstant;
import high.concurent.service.MailService;
import high.concurent.service.NotifyService;
import high.concurent.util.CaptchaUtil;
import high.concurrent.constant.CacheKey;
import high.concurrent.enums.BizCodeEnum;
import high.concurrent.enums.SendCodeEnum;
import high.concurrent.utils.CheckUtil;
import high.concurrent.utils.CommonUtil;
import high.concurrent.utils.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class NotifyServiceImpl implements NotifyService {


    /**
     * 图形验证码有效期10分钟
     */
    private static final long CAPTCHA_CODE_EXPIRED = 60 * 1000 * 10;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MailService mailService;

    /**
     * 获取图片验证码
     * @param response
     * @param captchaKey 用户id
     */
    @Override
    public void getCaptcha(Producer captchaProducer, HttpServletResponse response, String captchaKey) {

        // 获取图片验证码，并返回验证码值
        String captcha = CaptchaUtil.getCaptcha(captchaProducer, response);

        // 保存到redis
        redisTemplate.opsForValue().set(CacheKey.GRAPH_CODE_KEY + captchaKey, captcha, CAPTCHA_CODE_EXPIRED, TimeUnit.MILLISECONDS);
    }

    /**
     * 发送验证码（手机/邮箱）
     * @param sendCodeEnum  验证码类型
     * @param to         手机号 或者 邮箱
     * @param captcha    图片验证码
     * @param captchaKey    ip + 指纹拼接的图片验证码Key唯一标识部分
     * @return
     */
    @Override
    public JsonData sendCode(SendCodeEnum sendCodeEnum, String to, String captcha, String captchaKey) {

        // 获取图形验证码key，并获取验证码
        String  graphKey = CacheKey.GRAPH_CODE_KEY + captchaKey;
        String ridesGraphCaptcha = (String) redisTemplate.opsForValue().get(graphKey);

        // 获取验证码(邮箱/手机)
        String captchaCodeKey = CacheKey.CODE_KEY + to;
        String redisEmailCaptcha = (String) redisTemplate.opsForValue().get(captchaCodeKey);

        // 判断图形验证码是否正确，不区分大小写
        if(to != null && captcha != null && captcha.equalsIgnoreCase(ridesGraphCaptcha)){

            // 判断邮箱验证码是否为空
            if(StringUtils.isNotBlank(redisEmailCaptcha)){

                // 邮箱验证码不为空，再判断是否超过60秒
                long ttl = Long.parseLong(redisEmailCaptcha.split("_")[1]);
                if((System.currentTimeMillis() - ttl) / 1000 < 60){

                    // 间隔不知足60秒
                    return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
                }
            }

            // 生成6为随机验证码， 并保存到redis
            String randomCode = CommonUtil.getRandomCode(6);
            redisTemplate.opsForValue().set(captchaCodeKey, randomCode + "_" + System.currentTimeMillis(), 5, TimeUnit.MINUTES);

            // 判断是邮箱验证码还是手机验证码
            if(CheckUtil.isEmail(to)){

                // 删除图片验证码的redis
                redisTemplate.delete(graphKey);

                // 邮箱验证码
                mailService.sendMail(to, MailConstant.REGISTRY_EMAIL_SUBJECT, MailConstant.REGISTRY_EMAIL_CONTENT + randomCode);

                log.info("验证码发送成功");
                return JsonData.buildSuccess();

            }else{
                // TODO 手机验证码
                log.info("验证码发送成功");
                return JsonData.buildSuccess();
            }
        }else{
            log.info("验证码发送失败");
            // 没有传图形验证码
            return JsonData.buildResult(BizCodeEnum.CODE_CAPTCHA_NO_EXIST);
        }

    }


    /**
     * 验证码校验
     * @param captchaCode   用户输入的验证码
     * @param to   验证码key， 手机: 手机格式； 邮箱：邮箱格式， 直接拼接即可
     * @return
     */
    @Override
    public boolean checkCaptchaCode(String captchaCode, String to) {

        // 获取验证码的组合值(验证码格式:   code_时间戳)
        String redisCptchaCodeKey =  CacheKey.CODE_KEY + to;
        String redisCptchaCodeValue = (String) redisTemplate.opsForValue().get(redisCptchaCodeKey);

        // redis中验证码不为空
        if(StringUtils.isNotBlank(redisCptchaCodeValue)){

            // 分割出真正的验证码
            String redisRealCptchaCodeValue = redisCptchaCodeValue.split("_")[0];
            if(redisRealCptchaCodeValue.equals(captchaCode)){

                // 删除redis验证码，并返回成功
                redisTemplate.delete(redisCptchaCodeKey);
                return true;
            }
        }

        return false;
    }
}
